package com.sk.bilibili.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sk.bilibili.api.LiveApi;
import com.sk.bilibili.bean.LiveType;
import com.sk.bilibili.bean.Member;
import com.sk.bilibili.dto.LiveData;
import com.sk.bilibili.dto.LiveInfo;
import com.sk.bilibili.dto.PushInfo;
import com.sk.bilibili.other.R;
import com.sk.bilibili.utils.BSessionUtils;
import com.sk.bilibili.utils.LiveUtils;
import com.sk.bilibili.utils.WarpUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.springframework.beans.factory.annotation.Autowired;
import com.sk.bilibili.bean.Live;
import com.sk.bilibili.mapper.LiveMapper;

/**
 * @author 邵康
 * @date 2021/11/26 09:55
 */
@Service
public class LiveService extends ServiceImpl<LiveMapper, Live> {

    @Autowired
    private MinioService minioService;
    @Autowired
    private LiveUtils liveUtils;
    @Autowired
    private LiveApi liveApi;
    @Autowired
    private WarpUtils warpUtils;
    @Autowired
    private MemberService memberService;
    @Autowired
    private LiveTypeService liveTypeService;
    private static final String COVER_PATH = "live/cover/%s.jpg";
    private static final Pattern COVER_PATTERN = Pattern.compile("/(live/cover/.*jpg)");
    private static final String BG_PATH = "live/bg/%s.jpg";
    private static final Pattern BG_PATTERN = Pattern.compile("/(live/bg/.*jpg)");

    public R<Void> add(Live live) {
        live.setMemberId(BSessionUtils.getMemberId());
        live.setCover(minioService.add(live.getCoverFile(), COVER_PATH));
        live.setBg(minioService.add(live.getBgFile(), BG_PATH));
        live.setUrl(liveUtils.generateUrl());
        save(live);
        return R.success();
    }

    public R<Void> delete(Integer id) {
        Live temp = getById(id);
        minioService.delete(temp.getCover(), COVER_PATTERN);
        minioService.delete(temp.getBg(), BG_PATTERN);
        removeById(id);
        return R.success();
    }

    public R<Void> update(Live live) {
        Live temp = getById(live.getId());
        String cover = minioService.update(COVER_PATH, COVER_PATTERN, temp.getCover(), live.getCoverFile());
        live.setCover(cover);
        String url = minioService.update(BG_PATH, BG_PATTERN, temp.getBg(), live.getBgFile());
        live.setUrl(url);
        updateById(live);
        return R.success();
    }

    public R<IPage<Live>> pageSearch(LiveInfo liveInfo) {
        QueryWrapper<Live> queryWrapper=new QueryWrapper<>();
        queryWrapper.like("title",liveInfo.getKeyword());
        IPage<Live> res = page(liveInfo.page(), queryWrapper);
        res.getRecords().forEach(this::warpLive);
        return R.success(res);
    }

    public Live getRandomLive(){
        Live live=baseMapper.getRandomLive();
        warpLive(live);
        return live;
    }

    private void warpLive(Live live) {
        R<Member> member = memberService.getMember(live.getMemberId());
        live.getExtra().addExtra(member.getData());
        live.getExtra().addExtra(liveTypeService.getById(live.getLiveTypeId()));
    }

    public R<List<Live>> getHeaderLive() {
        LiveData[] liveData = liveApi.getHeaderLive();
        List<Live> res=new ArrayList<>();
        for (LiveData item : liveData) {
            res.add(warpUtils.warpLive(item));
        }
        return R.success(res);
    }

    public R<List<Live>> getRecommend(Integer page, Integer size) {
        List<Live> res=baseMapper.getNumLive(size);
        res.forEach(this::warpLive);
        if(res.size()<size){
            LiveData[] data = liveApi.getRecommendLive(page, size);
            int need=size - res.size();
            for (int i = 0; i < need; i++) {
                res.add(warpUtils.warpLive(data[i]));
            }
        }
        return R.success(res);
    }

    public R<List<Live>> getTypeLivePage(Integer page, Integer liveTypeId) {
        LiveType type = liveTypeService.getById(liveTypeId);
        LiveData[] data = liveApi.getTypeLive(type.getAreaId(), type.getSortType(), page);
        List<Live> res=new ArrayList<>();
        for (LiveData liveData:data){
            res.add(warpUtils.warpLive(liveData));
        }
        return R.success(res);
    }

    public R<List<Live>> getRank(Integer num) {
        return getRecommend(1,num);
    }

    public R<PushInfo> getPushInfo(Integer id) {
        Live live = getById(id);
        return R.success(liveUtils.generatePushInfo(live.getUrl()));
    }

    public R<List<Live>> getTypeLive(Integer liveTypeId) {
        LiveType type = liveTypeService.getById(liveTypeId);
        LiveData[] data = liveApi.getTypeLive(type.getAreaId(), type.getSortType(), 1);
        List<Live> res=new ArrayList<>();
        for (int i = 0; i < 4; i++) {
            res.add(warpUtils.warpLive(data[i]));
        }
        return R.success(res);
    }

    public Live getFullLive(Integer id) {
        Live live = getById(id);
        warpLive(live);
        return live;
    }

    public R<String> getLiveUrl(Integer roomId) {
        return R.success(liveApi.getLiveUrl(roomId));
    }

    public IPage<Live> searchLive(Page<Live> page, QueryWrapper<Live> queryWrapper) {
        IPage<Live> iPage = page(page, queryWrapper);
        iPage.getRecords().forEach(this::warpLive);
        return iPage;
    }

}
